查看原文
其他

云巢揭秘: 基于 TKE 构建数据库 PaaS 平台实践分享

孙勇福 腾讯云原生 2021-07-13


孙勇福,腾讯云数据库中心高级研发工程师,负责数据库中心云巢项目。多年从事数据库相关的运维和研发工作,在数据库存储领域有丰富的运维和研发经验。在17年接触云原生相关技术至今,对于数据库和云原生的结合有自己独到的见解。

数据库产品面临的问题

在腾讯云发展初期,为了抢占市场获取更多的用户,数据库经历一段时间的烟囱式发展。在那个时期我们中心有十几款数据库产品快速拉起。随着云的发展以及专有云的投入,更多业务团队也开始投入专有云的支持。同时业务的不断扩大,历史的架构模型弊端也逐渐凸显:

  1. 无法利用云上 IaaS 层的资源池和弹性扩缩容的能力,以及 IaaS 层成本和性能优化的红利
  2. 缺少统一的数据库 PaaS 平台,对多个产品、多个环境进行统一管控和调度
  3. 业务功能复用程度低,造成人力资源浪费
  4. 无法利用云原生红利,平台无法标准化,运维和交付成本比较高

上述问题,我们可以归纳为资源调度和统一的流程管控问题,CVM/VPC/CBS 等腾讯云基础产品经过十几年的发展,可以提供可靠稳定的基础 IaaS,我们认为当前基于云的 IaaS 去构建一个统一的 PaaS管控平台是可行的。

PaaS on IaaS 思考

依赖云上 IaaS 层构建 PaaS 同时还可以享受更多红利:

  1. 弹性共有的资源池,解决传统资源池闲置成本
  2. 依赖 IaaS 基础稳定性,可以提供SLA的保障
  3. 依赖 IaaS 基础设施的完备,更快的构建PaaS层设施
  4. 依赖 IaaS 技术红利,快速享受云上成本优势

如何去统一管理IaaS层的资源,是 PaaS on IaaS 面临的主要挑战。目前云原生已经进入2.0时代,提供了标准的 Devops/存储/容器/编排等相关能力,同时 TKE 产品形态在腾讯公有云运行多年,经历众多客户的考验,稳定性值得认可。基于 TKE 实现数据库领域的 PaaS on IaaS 成为一个可行方案。

利用云原生的能力,我们可以屏蔽底层的 IaaS 层的差异,实现一套代码多个环境复用,解决目前专有云和公有云两个环境差异严重的问题,保持用户体验统一。

云巢:PaaS on IaaS 平台

数据库产品中心利用云上的基础 IaaS(CVM/VPC/CBS) 以及TKE 进行了 PaaS on IaaS 方案试点,并成功稳定上线至今半年之久。在这期间我们具体做对了哪些事情,遇到哪些问题呢?在这里先从整体架构一点点说起。在 PaaS 平台设计中,整个业务分为三个层面:

  1. 业务接入层:业务和控制台交互的接入层,比如参数控制/计费等业务特性功能
  2. 云巢 PaaS 层:依赖云原生构建的 PaaS 平台
  3. 业务底层:业务内核镜像以及监控数据采集实现和部署层
  • scheduler: 云巢资源调度器模块,依赖 K8S scheduler-framework 扩展实现,提供数据库实例拓扑装箱能力

  • cluster_manger:数据库实例 CRD 的controller,负责数据库实例 CRD 调协工作

  • sidecar-container:云巢统一的 agent ,提供命令接收和执行以及配置下载部署等工作,是biz-container的伴生进程

  • biz-container:业务内核镜像,比如:redis/MySQL/Zookeeper 内核等

其中上述绿色部分是业务产品接入时需要关心的部分,整体上业务只关心两端:业务接入层和业务底层内核,中间控制层全部交给云巢 PaaS 平台。同时在云巢 PaaS 部分,我们复用 TKE 成熟的 K8s 管理经验和产品能力,对我们提供强有力的技术和产品能力支持。在方案设计中,我们将平台分为两个部分:

  1. 云巢资源管控平台,负责产品 CRD 的资源操作/配置管理/命令管理
  2. 云巢流程编排平台,负责业务流程调度以及业务状态管理和编排

在上述构建中我们可以通过 K8s 的 PV/Pod/ENI 等屏蔽业务层对底层 IaaS 的理解,提供 IaaS 的可插拔可替换的能力。

云巢资源管控平台

有状态服务区别于无状态服务主要是状态两个字,有状态服务往往伴随着数据持久化,服务节点状态化( MySQL 主从节点)。如何在复杂的状态服务中,更好的解耦业务逻辑,提供通用的平台能力是PaaS 平台设计的难点之一。在我们平台构建中,首先我们明确了平台的边界和业务边界,平台不应该关心业务的具体逻辑,也必须提供业务灵活的接入功能。云巢资源管控层只提供三能力:

  • 资源管理:提供 CRD (实例)的创建/升级/缩容/销毁等 资源分配管理能力

  • 配置管理:提供 CRD (实例),业务配置模版渲染/版本/创建/更新/发布 等能力,满足业务配置修改需求

  • 命令管理:提供 CRD (实例),同步/异步的任务下发和操作能力,比如重启 Biz-Container 等操作

所有的业务功能,围绕上层的三个能力进行业务逻辑构建。通过上述的抽象设计,业务只关心业务本身的业务 比如主从关系/配置项操作等编排工作,云巢资源平台提供业务资源管理的原子接口。

云巢任务编排平台

通过上述讨论,我们可以通过资源平台满足业务的资源管理需求,但是往往业务的复杂性来源于业务逻辑本身。比如对于 CDB 发货逻辑来讲:

  1. 资源发货
  2. 申请 VPC LB
  3. 绑定 路由
  4. 添加默认告警规则
  5. 按量计费结算推送

每个业务功能上线 都会经历几个或者几十个步骤,同时不同产品之间的业务逻辑也具备相似性。如何解决业务代码同质化保证业务质量呢?在这个背景下,云巢任务编排平台(目前开发中)应运而生。业务只需要关心原子同步命令业务代码实现,工作流负责各个原子步骤之间的编排和上下文切换以及计算资源的自动扩缩容。通过任务编排的解耦合能力,业务只需要关心每个原子任务的正确性,并且也提供了每个原子步骤的可复用性能力。对于复杂的业务逻辑,通过任务编排 UI 提供 DAG 描述的可视化编排,降低业务流程接入复杂度。

在云巢项目中,我们集成了 argo workflow[1],argo 是 Applatix 推出的一个开源项目,为 Kubernetes 提供 container-native(工作流中的每个步骤是通过容器实现)工作流程。Argo 可以让用户用一个类似于传统的 YAML 文件定义的 DSL 来运行多个步骤的 Pipeline。该框架提供了复杂的循环、条件判断、依赖管理等功能,这有助于提高部署应用程序的灵活性以及配置和依赖的灵活性。使用 Argo,用户可以定义复杂的依赖关系,以编程方式构建复杂的工作流、制品管理,可以将任何步骤的输出结果作为输入链接到后续的步骤中去,并且可以在可视化 UI 界面中监控调度的作业任务。它具备如下特点:

  1. 使用 Kubernetes 自定义资源(CR)定义工作流,其中工作流中的每个步骤都是一个容器

  2. 将多步骤工作流建模为一系列任务,或者使用有向无环图(DAG)描述任务之间的依赖关系

  3. 可以在短时间内轻松运行用于机器学习或数据处理的计算密集型作业

  4. 可以通过 argo workflows 运行 CI/CD 流水线(Pipielines)

下图是基于Argo 的发货流程 示例:

对应的 createresource-dsl-yaml 文件:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: createresourcewf
spec:
  entrypoint: createresourcewf
  templates:
    - name: createresourcewf
      steps:
        - - name: createresource
            template: createresource
        - - name: applyvip
            template: applyvip
            when: '{{steps.createresource.outputs.result}} == ok'
        - - name: addroute
            template: addroute
            when: '{{steps.createresource.outputs.result}} == ok'
    - name: createresource
      script:
        image: 'python:alpine3.6'
        command:
          - python
        source: |
          import random
          result = "ok"
          print(result)
    - name: applyvip
      container:
        image: 'alpine:3.6'
        command:
          - sh
          - '-c'
        args:
          - echo "it was ApplyVip"
    - name: addroute
      container:
        image: 'alpine:3.6'
        command:
          - sh
          - '-c'
        args:
          - echo "it was AddRoute"

我们可以很方便通过配置文件或者UI 界面快速的实现我们复杂的业务逻辑编排,通过编排组件实现 step 中间数据的保存和转换,可以大大简化业务实现 step 的逻辑。业务只需要关心每一个 step 原子执行即可,具体 step 如何扭转完全交给流程配置人员来处理。

云巢面临的挑战和解法

一般情况下对于 web server 数据会保存在专门做持久化的节点上,这些节点可以随意扩容或者缩容,只要简单的增加或减少副本的数量就可以。但是很多有状态的程序都需要集群式的部署,意味着节点需要形成群组关系,每个节点需要一个唯一的 ID(例如Kafka BrokerId[2], Zookeeper myid[3]) 来作为集群内部每个成员的标识,集群内节点之间进行内部通信时需要用到这些标识。同时对于数据库产品尤为特殊,数据库产品承载了用户的业务核心数据,数据安全是产品的红线,稳定性是数据库产品的核心。数据库产品品类众多,架构不一更带来了架构设计的难度,数据库产品需要解决几个技术难点:

  1. 弹性资源调度

  2. 多租户资源隔离

  3. 数据/网络安全

  4. 可靠性,可用性

在云巢平台构建过程中需要关注的技术点,我这里分为两类:

  1. 资源管理类:满足产品基本诉求,比如多租户资源隔离,弹性资源调度等
  2. 平台管控类:关注平台本身的核心组件或者解决方案, 比如配置中心/管控网络 等

资源管理类

弹性资源调度

数据库在用户使用场景下,往往担负着核心业务数据存储的角色,数据库的高可用是用户最基本的诉求。在使用 K8s 技术体系管理数据库实例过程中,解决实例 Pod 拓扑装箱满足高可用冗灾是首要要求。在这里我们可以利用 K8s 的 kube-Scheduler 来满足我们的要求。

Scheduler 负责 Pod 调度。在整个系统中起"承上启下"作用,承上:负责接收 Controller Manager 创建的新的 Pod 信息,为其选择一个合适的 Node;启下:Node 上的 Kubelet 接管 Pod 的生命周期。kube-scheduler 给一个 pod 做调度选择包含两个步骤:

  1. 过滤
  2. 打分

过滤阶段会将所有满足 Pod 调度需求的 Node 选出来。例如 Filter 过滤函数会检查候选 Node 的可用资源能否满足 Pod 的资源请求。在过滤之后,得出一个 Node 列表,里面包含了所有可调度节点;通常情况下, 这个 Node 列表包含不止一个 Node。如果这个列表是空的,代表这个 Pod 不可调度。

在打分阶段,调度器会为 Pod 从所有可调度节点中选取一个最合适的 Node。根据当前启用的打分规则,调度器会给每一个可调度节点进行打分。最后,kube-scheduler 会将 Pod 调度到得分最高的 Node 上。如果存在多个得分最高的 Node ,kube-scheduler 会从中随机选取一个。

目前 k8s-scheduler 支持以下两种方式配置调度器的过滤和打分行为:

  1. 调度策略允许你配置过滤的 断言( Predicates ) 和打分的 优先级(Priorities)
  2. 调度配置允许你配置实现不同调度阶段的插件,包括:Pre-filter, Filter, Pre-score, Scoring, Normalize scoring 等等。你也可以配置 kube-scheduler 运行不同的配置文件

通过k8s-scheduler的插件能力,我们可以实现自定义的调度过滤算法和打分算法,来满足数据实例对资源装箱的要求。

多租户资源隔离

在云上资源售卖中,为了提高售卖率,降低设备成本。我们往往选择多租户售卖模式,一台 Node 机器往往售卖给多个用户使用。这在提高售卖率的同时,也要求我们必须做好多租户资源隔离。我们都知道一台机器上部署多个进程,进程之间会出现 cpu/mem 等资源的抢占情况,当一个用户实例进行性能压测反而影响到另外一个实例性能。对于这种情况我们是完全不允许的,在使用 K8s 平台我们如何解决这一个问题呢?

我们可以利用两个技术,当然也是 docker 基石:

  1. namespace 技术:是 Linux 提供的一种内核级别环境隔离的方法,不同网络命名空间的网络协议栈是完全隔离的,之间无法通信
  2. cgroup 技术:是 Linux 内核的一个功能,用来限制,控制与分离一个进程组群的资源(如 CPU、内存、磁盘输入输出等)

数据存储层 PVC/PV

数据库往往离不开数据,数据持久化存储也是数据库核心要求,在 K8S 环境内如何自由的分配操作存储介质呢,在这里我们不得不简单谈一谈 PV/PVC。

PV/PVC详细可以参考[4] 持久卷(PersistentVolume,PV)是集群中的一块存储,可以由管理员事先供应,或者 使用存储类(Storage Class)来动态供应。持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样,也是使用 卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

持久卷申领(PersistentVolumeClaim,PVC)表达的是用户对存储的请求。概念上与 Pod 类似。Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。

在 K8S 内 PV 是如何挂载到容器内的呢?K8S 做了哪些事情?我们先看一下K8S核心组件图:

  • AD-Ctrl: 监听 API Server 的资源变化,主要监听的是node和pod资源,通过 node 和 pod 变更,触发 ADController 是否 attach/detach 操作,然后调用 plugin 做相应的业务处理。

  • PV-Ctrl: 监听 API Server 中的资源更新,对于卷管理主要是监听 PV,PVC, SC 三类资源,当监听到这些资源的创建、删除、修改时,PV Controller 经过判断是需要做创建、删除、绑定、回收等动作(后续会展开介绍内部逻辑),然后根据需要调用 Volume Plugins 进行业务处理。

  • Volume-Manager: VolumeManager 不会监听 API Server,在 Minion 端所有的资源监听都是 Kubelet 完成的,Kubelet 会监听到调度到该节点上的 pod 声明,会把 pod 缓存到 Pod Manager 中,VolumeManager 通过 Pod Manager 获取 PV/PVC 的状态,并进行分析出具体的 attach/detach, 操作然后调用 plugin 进行相应的业务处理

当一个POD需求到来时候, 一个 POD 从创建到PV绑定过程大概会经过如下几个步骤:

  1. apiServer: 为用户创建 Pod 包含一个 PVC

  2. scheduler: 捕捉到 创建事件,根据需要 Pod 被分配到节点 Node

  3. Kubelet-volume manager: 通过 pod map 感知到 pod volume 挂载信息,创建好需要的 device

  4. PV controller: 用相应 Volume Plugin (in-tree或者out-of-tree)创建持久化卷并在系统中创建 PV对象以及其与 PVC 的绑定 (Provision)

  5. Attach/Detach controller: 通过 Volume Plugin 实现块设备挂载(Attach)

  6. Volume Manager: 等待 device 设备挂载完成,将卷挂载到节点指定目录(mount)

  7. Kubelet: 在被告知设备准备好后启动 Pod 中的容器,利用 Docker –v 等参数将已经挂载到本地 的卷映射到容器中 (volume mapping)

从上述的过程中我们可以感知到,数据库产品对于存储相关的要求都会统一转换为 PV 操作,通过 PV 来屏蔽具体存储层介质(云盘/本地盘等),K8S会正确的处理 PV 的 mount/unmount 等操作。

数据网络安全

在云上产品托管服务中,产品安全问题也是经受层层考验。比如:Biz-Container 出现漏洞,是否会有使 Pod 成为肉鸡的可能。在这种情况下怎么样避免或者减少更大的损失。首先我们可以通过 K8s 的 [network policy ] (https://kubernetes.io/docs/concepts/services-networking/network-policies)能力提供 用户间的网络隔离, 当 Pod 出现被入侵的同时我们可以通过网络策略的隔离,避免危害扩大化。如下图:

同时:

  • Pod 维度流量限制,避免大流量操作 多租户实例影响。
  • 规范 Container 启动用户,避免 Root 提权限。
  • K8s pod 特权( privileged )关闭,限制业务最小化权限集合。

我们可以通过云原生技术方便的控制租户权限,避免危害扩大化。

平台管控类

业务灵活控制:Sidecar 模式选择

围绕数据库业务进程,我们往往需要设置一些 agent 进行进程的监控,即使感知业务进程的变化,保证进程的高可用,在容器场景下一般有两种选择方式:轻容器和富容器。1、富容器

富容器是企业打包业务应用、实现业务容器化过程中,采用的一种容器模式。通过富容器技术打包的业务应用可以达到两个目的:

  • 容器镜像实现业务的快速交付。

  • 容器环境兼容企业原有运维体系。

但是富容器往往富集更多的业务功能(相关业务进程一起镜像),在未来业务进程发展过程中,无法灵活控制,比如:配置变更/进程升级等

2、轻容器

轻容器也就是 Sidecar 模式。Sidecar 模式是 Service Mesh 中习惯采用的模式,是容器设计模式的一种。Sidecar 应用与主应用程序松散耦合。它可以统一实现微服务的可观察性、监控、日志记录、配置、断路器等功能。Sidecar 模式主要有以下优点:

  • 将与应用业务逻辑无关的功能抽象到共同基础设施降低了微服务代码的复杂度。

  • 因为不再需要编写相同的第三方组件配置文件和代码,所以能够降低微服务架构中的代码重复度。

  • 降低应用程序代码和底层平台的耦合度

对比轻容器和富容器的特点,轻容器的灵活度更高,集中控制和约束能力更强。同时也经过了 istio 的充分验证,轻容器更适用于当前 PaaS 平台的要求。

CRD 资源建模

在上文描述中我们知道,一个数据库实例一般具备 N 个 Pod 节点,如何描述和统一控制我们的实例资源,这里我们需要依赖 K8s 的 CRD 能力。CRD 的全称为 CustomResourceDefinitions即自定义资源。K8s 拥有一些内置的资源,比如说 Pod,Deployment,ReplicaSet 等等,而 CRD 则提供了一种方式,使用户可以自定义新的资源,以扩展 K8s 的功能。对于目前数据库常见类型基本上可以抽象为如下三层:

  • cluster: 集群纬度,描述整个集群信息,一个 cluster 可能有1到 n 个 set 组成

  • set: 一组同类型节点组成的 pod group , 例如 clickhouse 中的 zookeeper set 就是有 n 个的 zookeeper-pod 节点组成。在这里我们使用 statefulset[5] 的能力来管理 set

  • pod: 具体承载业务应用的单元

我们知道 Kubernetes 管理策略是一切皆对象(object) 所以我们可以基于 pod 最小对象单元,通过 set/cluster 等对象构建完成我们对数据库集群CRD 的定义。下面是我们 cluster struct 定义:

// Cluster is the spec for a Cluster resource
type ClusterSpec struct {
    BusinessType  string              `json:"businessType"` // category of this type of business, eg mysql, etcd ...
    SchedulerName string              `json:"schedulerName"`
    Sets          map[string]*SetSpec `json:"sets"`
}
// SetSpec is the static info for a set of k8s pod
type SetSpec struct {
    // meta
    Replicas  *int32 `json:"replicas"`  // number of replicas required
    PodSpec              v1.PodSpec                      `json:"podSpec"`
    PodManagementPolicy  appv1.PodManagementPolicyType   `json:"podManagementPolicy,omitempty" protobuf:"bytes,6,opt,name=podManagementPolicy,casttype=PodManagementPolicyType"`
    UpdateStrategy       appv1.StatefulSetUpdateStrategy `json:"updateStrategy,omitempty" protobuf:"bytes,7,opt,name=updateStrategy"`
    VolumeClaimTemplates []v1.PersistentVolumeClaim      `json:"volumeClaimTemplates,omitempty" protobuf:"bytes,4,rep,name=volumeClaimTemplates"`
}

这样我们就可以通过 CRD Controller 实现对数据库实例的控制。

配置中心

在业务服务过程中,一般需要大量的配置文件提供合理的启动参数,然而不同的业务类型配置文件千差万别,如何正确的处理这些配置文件是 PaaS 平台的关键。所以说配置中心在 PaaS 平台设计中属于核心组件,它是业务解耦的关键。配置中心是把项目中各种配置、各种参数、各种开关,全部都放到一个集中的地方进行统一管理,并提供一套标准的接口。当各个服务需要获取配置的时候,就来配置中心的接口拉取。通过配置中心我们可以实现业务配置的统一管理,通过配置模版可以屏蔽业务配置逻辑。

如上图所示,业务配置修改一般经历如下步骤:

  1. 用户通过 api-server 提供 CRD 参数修改
  2. 调谐器 watch 到 CRD 参数变化,此时会主动请求配置中心进行 CRD 的获取和配置模版的渲染工作
  3. 调谐器通过 agent 进行配置文件的下载和部署
  4. 调谐器通知配置部署结果

通过配置中心模版的解耦,使得平台只关心配置文件的版本管理/创建/回滚/下发等,具体配置逻辑交给业务进行配置模版的生成,实现业务和平台的分离工作。

日志监控平台

面对动辄几百上千个虚拟机、容器,数十种要监控的对象,现有的监控系统还能否支撑的住?来自于容器、虚拟机、物理机的应用日志、系统服务日志如何采用同一套方案快速、完整的收集和检索?怎样的架构、技术方案才更适合如此庞大繁杂的监控需求呢?我们可以利用云上的红利,快速构建TKE 云原生监控[6]
CLS 日志服务[7]

有状态服务

有状态服务管理主要体现在状态两个字,对于数据库产品服务除了要保证进程高可用之外,还要保证服务的状态正确性。比如对于 MySQL 数据库产品,我们需要实时维护数据库实例主从关系的正确性。对于 K8S 中 POD 出现重启以及重建等属于正常情况,但是对于数据库产品来讲这可能是灾难情况。比如用户要求 MySQl 主从必须跨 Zone 容灾,在 POD 出现重建情况时,必须满足产品快速恢复同时还要满足数据不能丢失的情况下满足跨 Zone 容灾需求。还有对于数据库产品我们往往要关注和控制业务进程级别,比如 MySQL 用户修改大小写敏感需要重启 mysqld 进程,这和 K8S 最小管理单元 POD 相冲突,如何利用 K8S 的技术点解决我们这些问题呢?首先我们来看一下 POD 的整个生命周期过程:

  1. init-container:可以提供我们业务进程操作之前的配置初始化工作,比如配置拉取以及环境初始化等
  2. pre_start_hook:可以提供我们进程启动之前一些预检查工作,比如配置合法性验证
  3. liveness/rediness/sidecar-agent:存在于业务进程的整个 runtime 周期,提供我们进程存活探测/进程重启管理/运行时配置修改等操作
  4. pre_stop_hook:可以提供我们容器消亡之前磁盘备份快照等操作(避免用户后悔)

通过 POD 生命周期过程分析,我们可以利用现有的一些 hook 来满足我们对业务进程的精细化控制。

1、有状态服务发货(MySQL 为例)

经过上述逐个具体问题点的描述,可能大部分读者心里还会有疑惑?比如:MySQL 要上云巢,具体它是怎么工作的呢?在这里我们就通过 MySQL 发货流程扭转,来带着大家感受一下云巢做的事情。如下图:

业务通过云巢的 ApiServer 的接口实现 MySQL 实例 CRD 的请求提交, 云巢会负责剩下的资源分配工作:

  1. cluster_manager 会通过 watch 监控到 CRD 创建事件,并封装 statefulset 对像以及PVC 对象请求
  2. Statefulset 控制器通过 watch 监控到上述 set 对象的创建事件 会进行 pod 对象封装请求
  3. scheduler 模块通过 watch 感知到 pod 的创建事件,通过 node 的筛选工作找到合适的 node
  4. 调协器在 CRD 资源分配完成后,根据 set 的启动顺序权重,按照顺序通过配置中心拉取MySQL进程的启动配置,并通过 init-container 下发配置,完成后告知 init-container 自杀完成 main-container/agent-container 的启动工作
  5. 调谐器会通过命令通道,执行主从关系的 Attach 操作,完成主从关系
  6. 调谐器通过统一的 health check 接口完成集群的健康检查,最后更新集群 CRD 为online 状态

所以通过上述过程替换为其他产品,业务只需要提供一下产品的配置和内核镜像以及命令通道的编排即可实现一款新的产品上线。

2、有状态服务HA (MySQL 为例)

根据上述的发货流程描述,大家大概有个初步的认识,这里再通过 MySQL 出现 Master 故障 HA 切换的场景进行一次描述,让大家整体了解云巢控制编排模块/云巢资源模块如何在服务中配合工作的。如下是 MySQL master 故障重做主机的过程简化流程图:

云巢会提供统一的拨测平台,业务可以配置自己的拨测策略。通过拨测平台可以感知到业务实例CRD 稳定情况,例如 MySQL master 发生故障并通过简单的进程拉起操作无法提供服务的情况:

  1. 拨测平台实时拨测业务进程情况,发现进程节点异常,并尝试进程拉起修复等操作修复失败(这个过程比较快一般是秒级别),此时会通过云巢控制流编排平台触发业务 HA 流程
  2. 云巢控制流编排平台接收到业务流程命令,主动寻找对应 HA-DSL-YAML 流程模型文件,驱动 HA 流程
  3. 云巢控制流编排平台按照step触发主从切换提供服务可用/重做从机/重做主从步骤等,最终提供实例高可用的稳定状态

在上述描述中业务同学只需要根据云巢资源平台的原子接口完成 HA-DSL-YAML 文件的编写和注册,其余的事情就可以交给云巢平台。

未来展望

数据库产品中心目前有种类繁多的 TP 类数据库,并且我们在数据库产品领域经验沉淀多年。同时 HTAP 类数据库目前刚刚布局,PaaS 可以依赖新兴 HTAP 数据库进行打磨试点,同时随着 NewSQL 数据库产品 TDSQL V3 等的接入,可以补充 Paas 平台在 TP 领域的布局,完善PaaS 的周边生态,同时借助云原生红利( Istio,Chaos 等开源组件)踩在巨人肩膀上提供一个可行的 PaaS On IaaS 方案,为早日实现两朵云(公有云和专有云)的统一做一点贡献。



互动赢好礼


精读本文,回答作者提问










阅读本文,回答作者提问,将于6月23日11点选出答案最佳2名及留言点赞最高的前3名,送腾讯云小云仔一只


Q:在数据库容器化之后,针对pod动态调整,如何保证数据库服务HA 数据一致性?






参考资料

[1]

argo workflow:【 https://github.com/argoproj/argo-workflows/】

[2]

Kafka BrokerId:【 https://kafka.apache.org/documentation/#impl_zkbroker】

[3]

Zookeeper myid: 【https://zookeeper.apache.org/doc/r3.3.2/zookeeperAdmin.html】

[4]

PV/PVC详细可以参考:【 https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/】

[5]

statefulset: 【https://kubernetes.io/docs/concepts/workloads/controllers/statefulset】

[6]

TKE 云原生监控:【 https://cloud.tencent.com/document/product/457/49889#null】

[7]

CLS 日志服务: 【https://cloud.tencent.com/document/product/614/47044#null】































  往期精选推荐  


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存